package com.glodon.paas.monitor.web.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.glodon.paas.consts.StringConst;
import com.glodon.paas.monitor.server.biz.domain.MonitorApplicationEntity;
import com.glodon.paas.monitor.server.biz.domain.MonitorUserAppEntity;
import com.glodon.paas.monitor.server.biz.domain.MonitorUserEntity;
import com.glodon.paas.monitor.server.constants.MonitorStatusEnum;
import com.glodon.paas.monitor.server.dto.MonitorApplicationDTO;
import com.glodon.paas.monitor.server.dto.MonitorApplicationUserDTO;
import com.glodon.paas.monitor.server.dto.MonitorResultMsg;
import com.glodon.paas.monitor.server.dto.MonitorUserDTO;
import com.glodon.paas.monitor.server.exposed.facade.MonitorAppUserFacadeService;
import com.glodon.paas.monitor.server.util.DateFormatUtil;
import com.glodon.paas.monitor.web.constants.MonitorWebPageConstants;

@Controller
public class MonitorAppController {

	@Autowired
	private MonitorAppUserFacadeService							monitorAppUserFacadeService;

	protected static ConcurrentHashMap<Long, MonitorUserEntity>	userCacheMap	= new ConcurrentHashMap<Long, MonitorUserEntity>();

	@RequestMapping(value = "appMain", method = RequestMethod.GET)
	public ModelAndView indexApp(@RequestParam(value = "appName", required = false) String appName,
			@RequestParam(value = "appStatus", required = false) String appStatus, ModelMap model,
			HttpServletRequest request) {

		boolean modelFlag = false;
		ModelMap doAppActionModel = (ModelMap) request.getSession().getAttribute("doAppModel");
		if (null != doAppActionModel && !doAppActionModel.isEmpty()) {
			modelFlag = true;
			appName = (String) doAppActionModel.get(StringConst.ITEM);
		}

		MonitorApplicationEntity appEntity = new MonitorApplicationEntity();
		if (StringUtils.isNotBlank(appName)) {
			appEntity.setAppName(appName);
		}

		if (StringUtils.isNotBlank(appStatus)) {
			appEntity.setAppStatus(appStatus);
		}

		MonitorResultMsg<ArrayList<MonitorApplicationEntity>> appResultMsg = monitorAppUserFacadeService
				.queryMonitorApplication(appEntity);

		if (null != appResultMsg) {
			if (appResultMsg.isSuccess()) {
				ArrayList<MonitorApplicationEntity> appList = (ArrayList<MonitorApplicationEntity>) appResultMsg
						.getResultObject();
				if (null != appList && !appList.isEmpty()) {
					ArrayList<MonitorApplicationDTO> appDTOList = new ArrayList<MonitorApplicationDTO>(appList.size());
					for (MonitorApplicationEntity app : appList) {
						MonitorApplicationDTO appDTO = new MonitorApplicationDTO();
						BeanUtils.copyProperties(app, appDTO);
						buildAppDTOForUserName(appDTO);
						appDTOList.add(appDTO);
					}
					model.addAttribute(StringConst.ITEMS, appDTOList);
					model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
				}
			} else {
				model.addAttribute(StringConst.RESULT, StringConst.FAIL);
				model.addAttribute(StringConst.RETURN_MSG, appResultMsg.getResultMsg());
			}
		} else {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.QUERY_RESULT_EMPTY);
		}

		if (modelFlag) {
			model.addAttribute(StringConst.RETURN_MSG, doAppActionModel.get(StringConst.RETURN_MSG));
			model.addAttribute(StringConst.RESULT, doAppActionModel.get(StringConst.RESULT));
			request.getSession().removeAttribute("doAppModel");
		}

		return new ModelAndView("appMain", model);
	}

	/**
	 * 构造应用的负责人用户信息
	 * 
	 * @param appDTO
	 */
	private void buildAppDTOForUserName(MonitorApplicationDTO appDTO) {
		MonitorResultMsg<MonitorApplicationUserDTO> appUserMsg = monitorAppUserFacadeService
				.findMonitorApplicationUser(appDTO.getId());
		if (null != appUserMsg && appUserMsg.isSuccess()) {
			MonitorApplicationUserDTO appUserDTO = (MonitorApplicationUserDTO) appUserMsg.getResultObject();
			List<MonitorUserAppEntity> monitorUserAppList = (List<MonitorUserAppEntity>) appUserDTO
					.getMonitorUserAppList();
			if (null != monitorUserAppList && !monitorUserAppList.isEmpty()) {
				StringBuilder userInfo = new StringBuilder();
				int len = monitorUserAppList.size();
				int i = 0;
				for (MonitorUserAppEntity userAppEntity : monitorUserAppList) {
					if (null == userCacheMap.get(userAppEntity.getUserId())) {
						MonitorResultMsg<MonitorUserEntity> userMsg = monitorAppUserFacadeService
								.findMonitorUser(userAppEntity.getUserId());
						if (null != userMsg && userMsg.isSuccess()) {
							MonitorUserEntity user = (MonitorUserEntity) userMsg.getResultObject();
							if (null != user && StringUtils.isNotBlank(user.getUserName())) {
								userCacheMap.put(user.getId(), user);
								userInfo.append("[" + user.getUserName() + "," + user.getPhoneNum() + "]");
								if (i < len - 1) {
									userInfo.append(",");
								}
							}
						}
					} else {
						MonitorUserEntity user = (MonitorUserEntity) userCacheMap.get(userAppEntity.getUserId());
						if (null != user && StringUtils.isNotBlank(user.getUserName())) {
							userInfo.append("[" + user.getUserName() + "," + user.getPhoneNum() + "]");
							if (i < len - 1) {
								userInfo.append(",");
							}
						}
					}
					i++;
				}
				appDTO.setUserInfo(userInfo.toString());
			}
		}
	}

	@RequestMapping(value = "appAction", method = RequestMethod.GET)
	public ModelAndView indexAppAction(@RequestParam(value = "id", required = false) Long id, ModelMap model) {
		MonitorResultMsg<MonitorApplicationUserDTO> resultMsg = monitorAppUserFacadeService
				.findMonitorApplicationUser(id);
		List<MonitorUserEntity> monitorUserList = null;
		if (null != resultMsg && resultMsg.isSuccess()) {
			MonitorApplicationUserDTO appUserDto = (MonitorApplicationUserDTO) resultMsg.getResultObject();
			MonitorApplicationEntity monitorApplication = appUserDto.getMonitorApplicationEntity();
			monitorUserList = appUserDto.getMonitorUserList();
			if (null != monitorApplication) {
				model.addAttribute("app", monitorApplication);
			}
		}
		MonitorUserEntity userEntity = new MonitorUserEntity();
		MonitorResultMsg<ArrayList<MonitorUserEntity>> userMsg = monitorAppUserFacadeService
				.queryMonitorUser(userEntity);
		if (null != userMsg && userMsg.isSuccess()) {
			ArrayList<MonitorUserEntity> userList = (ArrayList<MonitorUserEntity>) userMsg.getResultObject();
			if (null != userList && !userList.isEmpty()) {
				ArrayList<MonitorUserDTO> userDTOList = new ArrayList<MonitorUserDTO>();
				if (null != monitorUserList && !monitorUserList.isEmpty()) {
					Map<Long, MonitorUserEntity> userMap = new HashMap<Long, MonitorUserEntity>();
					for (MonitorUserEntity entity : monitorUserList) {
						if (null == userMap.get(entity.getId())) {
							userMap.put(entity.getId(), entity);
						}
					}
					for (MonitorUserEntity user : userList) {
						MonitorUserDTO userDTO = new MonitorUserDTO();
						BeanUtils.copyProperties(user, userDTO);
						if (null != userMap.get(userDTO.getId())) {
							userDTO.setSelectValue(true);
						}
						userDTOList.add(userDTO);
					}
					model.addAttribute("userList", userDTOList);
				} else {
					for (MonitorUserEntity user : userList) {
						MonitorUserDTO userDTO = new MonitorUserDTO();
						BeanUtils.copyProperties(user, userDTO);
						userDTOList.add(userDTO);
					}
					model.addAttribute("userList", userDTOList);
				}
			}
		}
		model.addAttribute("appId", id);
		return new ModelAndView("appAction", model);
	}

	@RequestMapping(value = "doAppAction", method = RequestMethod.POST)
	public ModelAndView doAppAction(@RequestParam(value = "appId", required = false) Long appId,
			@RequestParam(value = "appName", required = false) String appName,
			@RequestParam(value = "appDesc", required = false) String appDesc,
			@RequestParam(value = "appInstanceNum", required = false) Integer appInstanceNum,
			@RequestParam(value = "effectiveInterval", required = false) Integer effectiveInterval,
			@RequestParam(value = "userIds", required = false) String userIds, ModelMap model,
			HttpServletRequest request) {

		if (StringUtils.isBlank(userIds)) {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.INVALID_PARAMETER + ",userId is null.");
			model.addAttribute(StringConst.ITEM, appName);
			request.getSession().setAttribute("doAppModel", model);
			return new ModelAndView(new RedirectView("appMain"));
		}

		String userId[] = userIds.split(",");
		List<String> userIdList = new ArrayList<String>(Arrays.asList(userId));

		if (null != appId) {
			MonitorResultMsg<MonitorApplicationUserDTO> resultMsg = monitorAppUserFacadeService
					.findMonitorApplicationUser(appId);
			if (null != resultMsg && resultMsg.isSuccess()) {
				MonitorApplicationUserDTO appUserDto = (MonitorApplicationUserDTO) resultMsg.getResultObject();
				MonitorApplicationEntity monitorApplication = appUserDto.getMonitorApplicationEntity();
				if (null != monitorApplication) {
					monitorApplication.setAppName(appName);
					monitorApplication.setAppDesc(appDesc);
					monitorApplication.setAppInstanceNum(appInstanceNum);
					monitorApplication.setEffectiveInterval(effectiveInterval);
					if (null != effectiveInterval) {
						monitorApplication.setEffectiveTime(DateFormatUtil.parse(DateFormatUtil
								.getIntervalMinute(effectiveInterval)));
					}
					monitorApplication.setUpdateTime(new Date());
				}

				MonitorResultMsg<MonitorApplicationEntity> appResultMsg = monitorAppUserFacadeService
						.updateMonitorApplicationUser(monitorApplication, userIdList);
				if (null != appResultMsg) {
					if (appResultMsg.isSuccess()) {
						model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
						model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.UPDATE_SUCCESS);
					} else {
						model.addAttribute(StringConst.RESULT, StringConst.FAIL);
						model.addAttribute(StringConst.RETURN_MSG, appResultMsg.getResultMsg());
					}
				} else {
					model.addAttribute(StringConst.RESULT, StringConst.FAIL);
					model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.UPDATE_FAIL);
				}
			}
		} else {
			MonitorApplicationEntity monitorApplication = new MonitorApplicationEntity();
			monitorApplication.setAppName(appName);
			monitorApplication.setAppDesc(appDesc);
			monitorApplication.setAppInstanceNum(appInstanceNum);
			monitorApplication.setEffectiveInterval(effectiveInterval);
			if (null != effectiveInterval) {
				monitorApplication.setEffectiveTime(DateFormatUtil.parse(DateFormatUtil
						.getIntervalMinute(effectiveInterval)));
			}
			monitorApplication.setCreateTime(new Date());
			monitorApplication.setAppStatus(MonitorStatusEnum.OFF.getCode());

			MonitorResultMsg<MonitorApplicationEntity> appUserResultMsg = monitorAppUserFacadeService
					.saveMonitorApplicationUser(monitorApplication, userIdList);
			if (null != appUserResultMsg) {
				if (appUserResultMsg.isSuccess()) {
					model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
					model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.CREATE_SUCCESS);
				} else {
					model.addAttribute(StringConst.RESULT, StringConst.FAIL);
					model.addAttribute(StringConst.RETURN_MSG, appUserResultMsg.getResultMsg());
				}
			} else {
				model.addAttribute(StringConst.RESULT, StringConst.FAIL);
				model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.CREATE_FAIL);
			}
		}
		model.addAttribute(StringConst.ITEM, appName);
		request.getSession().setAttribute("doAppModel", model);
		return new ModelAndView(new RedirectView("appMain"));
	}

	@RequestMapping(value = "deleteApp", method = RequestMethod.GET)
	public ModelAndView doAppDelete(@RequestParam("id") Long id, ModelMap model, HttpServletRequest request) {
		if (null == id) {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.INVALID_PARAMETER);
			request.getSession().setAttribute("doAppModel", model);
			return new ModelAndView(new RedirectView("appMain"));
		}
		MonitorResultMsg<Boolean> resultMsg = monitorAppUserFacadeService.deleteMonitorApplicationUser(id);
		if (null != resultMsg) {
			if (resultMsg.isSuccess()) {
				model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
				model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.DELETE_SUCCESS);
			} else {
				model.addAttribute(StringConst.RESULT, StringConst.FAIL);
				model.addAttribute(StringConst.RETURN_MSG, resultMsg.getResultMsg());
			}
		} else {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.DELETE_FAIL);
		}
		request.getSession().setAttribute("doAppModel", model);
		return new ModelAndView(new RedirectView("appMain"));
	}

	@RequestMapping(value = "changeStatusApp", method = RequestMethod.GET)
	public ModelAndView doAppChangeStatus(@RequestParam("id") Long id, @RequestParam("appStatus") String appStatus,
			ModelMap model, HttpServletRequest request) {
		if (null == id || StringUtils.isBlank(appStatus)) {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.INVALID_PARAMETER);
			request.getSession().setAttribute("doAppModel", model);
			return new ModelAndView(new RedirectView("appMain"));
		}

		MonitorResultMsg<MonitorApplicationEntity> resultMsg = monitorAppUserFacadeService.changeMonitorAppStatus(id,
				appStatus);
		if (null != resultMsg) {
			if (resultMsg.isSuccess()) {
				MonitorApplicationEntity entity = (MonitorApplicationEntity) resultMsg.getResultObject();
				model.addAttribute(StringConst.ITEM, entity.getAppName());
				model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
				model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.CHANGE_SUCCESS);
			} else {
				model.addAttribute(StringConst.RESULT, StringConst.FAIL);
				model.addAttribute(StringConst.RETURN_MSG, resultMsg.getResultMsg());
			}
		} else {
			model.addAttribute(StringConst.RESULT, StringConst.FAIL);
			model.addAttribute(StringConst.RETURN_MSG, MonitorWebPageConstants.CHANGE_FAIL);
		}

		request.getSession().setAttribute("doAppModel", model);
		return new ModelAndView(new RedirectView("appMain"));
	}
}
